/*
* (C) Copyright 2013 Philip Kirchhoff 
* 
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
* 
*-------------------------------------------------------------------------------
* This file is part of the DataLogger library by Philip Kirchhoff
* https://code.google.com/p/pk-data-logger/
* SVN: http://pk-data-logger.googlecode.com/svn/trunk
*-------------------------------------------------------------------------------
* Module    : DlFloatChannel.cpp   
* Author    : Kirchhoff, Philip
* Date      : 01.04.2013
*-------------------------------------------------------------------------------
* Function definitions for class DlFloatChannel
*   
*-------------------------------------------------------------------------------
* Change History:
* 01.04.2013  Kirchhoff 	Created
--------------------------------------------------------------------------------
*/

#include <stdexcept>
#include <sstream>

#include "DlFloatChannel.h"

using namespace std;

/**************************************************************************//**
* @brief Constructs an empty analog channel with number, ID and unit
* @param channelNum Channel number 1...999999
* @param channelId ID of the channel
* @param channelUnit Physical unit of the channel
******************************************************************************/
DlFloatChannel::DlFloatChannel(unsigned int channelNum,
                               string channelId,
                               string channelUnit,
                               string channelDescr)
    : DlDataChannel(TYPE_FLOAT, channelNum, channelId, channelUnit, channelDescr),
      mChannelMultiplier(1.0), mChannelOffset(0.0),
      mChannelMin(-(std::numeric_limits<float>::max())),
      mChannelMax(std::numeric_limits<float>::max())
{
}

/**************************************************************************//**
* @brief Destructor
******************************************************************************/
DlFloatChannel::~DlFloatChannel()
{

}

/**************************************************************************//**
* @brief Sets the channels value range
* @param min Minimum alowed value of stored samples
* @param max Maximum alowed value of stored samples
******************************************************************************/
void DlFloatChannel::setRange(float min, float max)
{
    std::string excString(__PRETTY_FUNCTION__);
    if(max <= min)
    {
        excString += ": Invalid range (max <= min)!";
        throw std::range_error(excString.c_str());
    }

    mChannelMin = min;
    mChannelMax = max;
}

/**************************************************************************//**
* @brief Adds a sample to the channel
* @param sample Sample value
* \details Please note that if the value exceeds the defines range, it will
*			be stored as range-min or -max. Additionally an std::range_error
*			will be thrown.
******************************************************************************/
void DlFloatChannel::addSample(float &sample)
{
    if(sample < mChannelMin || sample > mChannelMax)
    {
        std::string excString(__PRETTY_FUNCTION__);
        excString += ": value exceeds defined range!";
        throw std::range_error(excString.c_str());
    }
    mData.push_back(sample);
}

/**************************************************************************//**
* @brief Adds a sample to the channel
* @param pSample Pointer to the sample (Should be of type long)
* \details Please note that if the value exceeds the defines range, it will
*			be stored as range-min or -max. Additionally an std::range_error
*			will be thrown.
******************************************************************************/
void DlFloatChannel::addSample(float *pSample)
{
    float sample = *pSample;

    if(sample < mChannelMin || sample > mChannelMax)
    {
        std::string excString(__PRETTY_FUNCTION__);
        excString += ": value exceeds defined range!";
        throw std::range_error(excString.c_str());
    }
    mData.push_back(sample);
}

/**************************************************************************//**
* @brief Reads a specified sample from the channel
* @param sampleNum Sample number
* \details If sampleNum exceeds the number of stored samples
*			an std::range_error will be thrown.
******************************************************************************/
float DlFloatChannel::sample(unsigned int sampleNum)
{
    if(sampleNum > mData.size()-1)
    {
        std::string excString(__PRETTY_FUNCTION__);
        excString += ": invalid sample number!";
        throw std::range_error(excString.c_str());
    }
    return mData[sampleNum];
}

/**************************************************************************//**
* @brief Get a string-converted sample
* @param sampleNum Sample number
* @return Sample value string
******************************************************************************/
std::string DlFloatChannel::sampleString(unsigned int sampleNum)
{
    stringstream ss;
    ss << sample(sampleNum);
    return ss.str();
}
